NexusPi Git Node
lib/microReticulum/src/Interface.cpp 42f0eec7b1d36b6153a0236dbede61646ceb2e39 (42f0eec7) Text, 4.94 KB
Tff7b72#Tff7b72include T8b949e"Interface.h"
Tff7b72#Tff7b72include T8b949e"Identity.h"
Tff7b72#Tff7b72include T8b949e"Transport.h"
Tff7b72#Tff7b72include T8b949e"Reticulum.h"
Tff7b72#Tff7b72include T8b949e"Cryptography/Hashes.h"
Tff7b72#Tff7b72include T8b949e"Cryptography/HKDF.h"
Tff7b72using Tff7b72namespace T7ee787RNSTb4b4b4;
Tff7b72using Tff7b72namespace T7ee787RNSTff7b72:Tff7b72:T7ee787TypeTff7b72:Tff7b72:T7ee787InterfaceTb4b4b4;
T8b949e/*static*/ Tffa657uint8_t Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3DISCOVER_PATHS_FOR Tff7b72= Te6edf3MODE_ACCESS_POINT Tff7b72| Te6edf3MODE_GATEWAYTb4b4b4;
Tffa657void Td2a8ffInterface::setup_ifacTb4b4b4(Tff7b72const Tffa657charTff7b72* Te6edf3ifac_netnameTb4b4b4, Tff7b72const Tffa657charTff7b72* Te6edf3ifac_netkeyTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_implTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3ifac_netname Tff7b72=Tff7b72= Tffa657nullptr Tff7b72&Tff7b72& Te6edf3ifac_netkey Tff7b72=Tff7b72= Tffa657nullptrTb4b4b4) Tb4b4b4{
Tff7b72returnTb4b4b4;
Tb4b4b4}
T8b949e// If both are empty strings, treat as no IFAC
Tffa657bool Te6edf3has_netname Tff7b72= Tb4b4b4(Te6edf3ifac_netname Tff7b72!Tff7b72= Tffa657nullptr Tff7b72&Tff7b72& Te6edf3ifac_netnameTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72!Tff7b72= Ta5d6ff'Ta5d6ff\0Ta5d6ff'Tb4b4b4)Tb4b4b4;
Tffa657bool Te6edf3has_netkey Tff7b72= Tb4b4b4(Te6edf3ifac_netkey Tff7b72!Tff7b72= Tffa657nullptr Tff7b72&Tff7b72& Te6edf3ifac_netkeyTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72!Tff7b72= Ta5d6ff'Ta5d6ff\0Ta5d6ff'Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3has_netname Tff7b72&Tff7b72& Tff7b72!Te6edf3has_netkeyTb4b4b4) Tb4b4b4{
Tff7b72returnTb4b4b4;
Tb4b4b4}
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffInterface::setup_ifac: setting up IFAC for Ta5d6ff" Tff7b72+ Te6edf3_implTff7b72-Tff7b72>Te6edf3_nameTb4b4b4)Tb4b4b4;
T8b949e// Build ifac_origin = SHA256(netname) || SHA256(netkey)
Te6edf3Bytes Te6edf3ifac_originTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3has_netnameTb4b4b4) Tb4b4b4{
Te6edf3Bytes Te6edf3netname_bytesTb4b4b4(Tb4b4b4(Tff7b72const Tffa657uint8_tTff7b72*Tb4b4b4)Te6edf3ifac_netnameTb4b4b4, Te6edf3strlenTb4b4b4(Te6edf3ifac_netnameTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3hash Tff7b72= Te6edf3IdentityTff7b72:Tff7b72:Te6edf3full_hashTb4b4b4(Te6edf3netname_bytesTb4b4b4)Tb4b4b4;
Te6edf3ifac_origin Tff7b72= Te6edf3ifac_origin Tff7b72+ Te6edf3hashTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3has_netkeyTb4b4b4) Tb4b4b4{
Te6edf3Bytes Te6edf3netkey_bytesTb4b4b4(Tb4b4b4(Tff7b72const Tffa657uint8_tTff7b72*Tb4b4b4)Te6edf3ifac_netkeyTb4b4b4, Te6edf3strlenTb4b4b4(Te6edf3ifac_netkeyTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3hash Tff7b72= Te6edf3IdentityTff7b72:Tff7b72:Te6edf3full_hashTb4b4b4(Te6edf3netkey_bytesTb4b4b4)Tb4b4b4;
Te6edf3ifac_origin Tff7b72= Te6edf3ifac_origin Tff7b72+ Te6edf3hashTb4b4b4;
Tb4b4b4}
T8b949e// Hash the combined origin
Te6edf3Bytes Te6edf3ifac_origin_hash Tff7b72= Te6edf3IdentityTff7b72:Tff7b72:Te6edf3full_hashTb4b4b4(Te6edf3ifac_originTb4b4b4)Tb4b4b4;
T8b949e// Derive ifac_key via HKDF(salt=IFAC_SALT, ikm=ifac_origin_hash, length=64)
Te6edf3Bytes Te6edf3saltTb4b4b4(Te6edf3IFAC_SALTTb4b4b4, Te6edf3IFAC_SALT_SIZETb4b4b4)Tb4b4b4;
Te6edf3_implTff7b72-Tff7b72>Te6edf3_ifac_key Tff7b72= Te6edf3CryptographyTff7b72:Tff7b72:Te6edf3hkdfTb4b4b4(T79c0ff64Tb4b4b4, Te6edf3ifac_origin_hashTb4b4b4, Te6edf3saltTb4b4b4)Tb4b4b4;
T8b949e// Create an identity from the derived key (64 bytes = 32 X25519 + 32 Ed25519)
Te6edf3Identity Te6edf3ifac_idTb4b4b4(Tffa657falseTb4b4b4)Tb4b4b4; T8b949e// don't auto-generate keys
Te6edf3ifac_idTb4b4b4.Te6edf3load_private_keyTb4b4b4(Te6edf3_implTff7b72-Tff7b72>Te6edf3_ifac_keyTb4b4b4)Tb4b4b4;
Te6edf3_implTff7b72-Tff7b72>Te6edf3_ifac_id Tff7b72= Te6edf3ifac_idTb4b4b4;
T8b949e// Set _ifac_identity to non-empty to flag IFAC as enabled
T8b949e// (Transport checks this with operator bool)
Te6edf3_implTff7b72-Tff7b72>Te6edf3_ifac_identity Tff7b72= Te6edf3ifac_idTb4b4b4.Te6edf3get_public_keyTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffInterface::setup_ifac: IFAC configured, ifac_size=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3_implTff7b72-Tff7b72>Te6edf3_ifac_sizeTb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657void Td2a8ffInterfaceImpl::handle_outgoingTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3dataTb4b4b4) Tb4b4b4{
T8b949e//TRACE("InterfaceImpl.handle_outgoing: data: " + data.toHex());
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffInterfaceImpl.handle_outgoingTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3_txb Tff7b72+Tff7b72= Te6edf3dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657void Td2a8ffInterfaceImpl::handle_incomingTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3dataTb4b4b4) Tb4b4b4{
T8b949e//TRACE("InterfaceImpl.handle_incoming: data: " + data.toHex());
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffInterfaceImpl.handle_incomingTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3_rxb Tff7b72+Tff7b72= Te6edf3dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// Create temporary Interface encapsulating our own shared impl
Te6edf3stdTff7b72:Tff7b72:Te6edf3shared_ptrTff7b72<Te6edf3InterfaceImplTff7b72> Te6edf3self Tff7b72= Te6edf3shared_from_thisTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3Interface Te6edf3interfaceTb4b4b4(Te6edf3selfTb4b4b4)Tb4b4b4;
T8b949e// Pass data on to transport for handling
Te6edf3TransportTff7b72:Tff7b72:Te6edf3inboundTb4b4b4(Te6edf3dataTb4b4b4, Te6edf3interfaceTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657void Td2a8ffInterface::handle_incomingTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3dataTb4b4b4) Tb4b4b4{
T8b949e//TRACE("Interface.handle_incoming: data: " + data.toHex());
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffInterface.handle_incomingTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3assertTb4b4b4(Te6edf3_implTb4b4b4)Tb4b4b4;
T8b949e/*
_impl->_rxb += data.size();
// Pass data on to transport for handling
Transport::inbound(data, *this);
*/
Te6edf3_implTff7b72-Tff7b72>Te6edf3handle_incomingTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657void Td2a8ffInterface::process_announce_queueTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e/*
if not hasattr(self, "announce_cap"):
self.announce_cap = RNS.Reticulum.ANNOUNCE_CAP
if hasattr(self, "announce_queue"):
try:
now = time.time()
stale = []
for a in self.announce_queue:
if now > a["time"]+RNS.Reticulum.QUEUED_ANNOUNCE_LIFE:
stale.append(a)
for s in stale:
if s in self.announce_queue:
self.announce_queue.remove(s)
if len(self.announce_queue) > 0:
min_hops = min(entry["hops"] for entry in self.announce_queue)
entries = list(filter(lambda e: e["hops"] == min_hops, self.announce_queue))
entries.sort(key=lambda e: e["time"])
selected = entries[0]
double now = OS::time();
uint32_t wait_time = 0;
if (_impl->_bitrate > 0 && _impl->_announce_cap > 0) {
uint32_t tx_time = (len(selected["raw"])*8) / _impl->_bitrate;
wait_time = (tx_time / _impl->_announce_cap);
}
_impl->_announce_allowed_at = now + wait_time;
self.on_outgoing(selected["raw"])
if selected in self.announce_queue:
self.announce_queue.remove(selected)
if len(self.announce_queue) > 0:
timer = threading.Timer(wait_time, self.process_announce_queue)
timer.start()
except Exception as e:
self.announce_queue = []
RNS.log("Error while processing announce queue on "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
RNS.log("The announce queue for this interface has been cleared.", RNS.LOG_ERROR)
*/
Tb4b4b4}
T8b949e/*
void ArduinoJson::convertFromJson(JsonVariantConst src, RNS::Interface& dst) {
TRACE(">>> Deserializing Interface");
TRACE(">>> Interface pre: " + dst.debugString());
if (!src.isNull()) {
RNS::Bytes hash;
hash.assignHex(src.as<const char*>());
TRACE(">>> Querying Transport for Interface hash " + hash.toHex());
// Query transport for matching interface
dst = Transport::find_interface_from_hash(hash);
TRACE(">>> Interface post: " + dst.debugString());
}
else {
dst = {RNS::Type::NONE};
TRACE(">>> Interface post: " + dst.debugString());
}
}
*/
Served by rngit 1.4.2 - Generated in 0.02s